package com.zq.vaccinum.filter;

import com.zq.vaccinum.constant.Constants;
import com.zq.vaccinum.domain.LoginUser;
import com.zq.vaccinum.util.JwtTokenUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.security.sasl.AuthenticationException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Objects;

/**
 * 访问验证拦截器
 * @Author: zq
 * @Date: 2023/08/04/2:14
 * @Description:
 */
@Component
public class JwtAuthFilter extends OncePerRequestFilter {

    @Autowired
    private RedisTemplate redisTemplate;

    /*
    * 对用户访问资源的HTTP请求头处理
    * */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取请求头的token
//        String token = request.getHeader("token");
//        if (!request.getMethod().equals("OPTIONS")) {
//            token = request.getHeader("token");
//            if (!StringUtils.hasText(token)) {
//                token = request.getParameter("token");
//                chain.doFilter(request, response);
//                return;
//            }
//        }
        // 从cookie取出token
        Cookie[] cookies = request.getCookies();
        String token = null;
        if(cookies != null){
            for(Cookie cookie : cookies){
                if(cookie.getName().equals("token")){
                    token = cookie.getValue();
                }
            }
        }

        // token为空,放行=>UsernamePasswordAuthenticationFilter,进行登录验证
        if (!StringUtils.hasText(token)) {
            chain.doFilter(request, response);
            return;
        }


        Claims claims = JwtTokenUtil.parseToken(token);
        // 从token里获取Token Key
        String tokenKey = (String) claims.get(Constants.LOGIN_USER_KEY);
        System.out.println("tokenKey:" + tokenKey);
        // 根据Token Key从redis获取用户信息
        String redisTokenKey = Constants.LOGIN_TOKENS + tokenKey;
        System.out.println("redisTokenKey:" + tokenKey);
        LoginUser loginUser = (LoginUser) redisTemplate.opsForValue().get(redisTokenKey);
//        LoginUser loginUser = redisCache.getCacheObject(redisTokenKey);
        // 如果redis找不到，说明用户未登录
        // 认证失败
        if (Objects.isNull(loginUser)){
            throw new AuthenticationException();
        }
        // 获取权限信息
        Collection<? extends GrantedAuthority> authorities = loginUser.getAuthorities();
        // 用户主体，凭证，是否已验证(默认true)
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, authorities);
        // 授权失败，token为空
        if (authenticationToken == null){
            chain.doFilter(request,response);
            return;
        }
        // 如果由授权，放到权限上下文中
        // 将权限信息封装到Authentication中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request,response);
    }

}
